package utils

import (
	"bytes"
	"embed"
	"io/ioutil"
	"os"
	"os/exec"
	"text/template"
)

// 根据模板创建文件
func WriteFileByTemplate(temp embed.FS, sourcePath, targetPath string, data map[string]interface{}) error {
	tempFile, err := temp.ReadFile(sourcePath)
	if err != nil {
		return err
	}

	var file []byte

	if data != nil {
		file, err = ApplyTemplate(string(tempFile), data)
		if err != nil {
			return err
		}
	} else {
		file = tempFile
	}

	_, err = WriteFile(targetPath, file)
	return err
}

// 写文件
func WriteFile(path string, data []byte) (int, error) {
	f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
	if err != nil {
		return 0, err
	}
	defer f.Close()

	return f.Write(data)
}

// 读取文件
func ReadFile(path string) ([]byte, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	return ioutil.ReadAll(f)
}

// 渲染模板
func ApplyTemplate(temp string, data map[string]interface{}) ([]byte, error) {
	var out bytes.Buffer
	t := template.Must(template.New("now").Parse(temp))
	err := t.Execute(&out, data)
	if err != nil {
		return nil, err
	}
	return out.Bytes(), nil
}

func ExecCommandGitWithRoot(cmd, path string) (string, error) {
	pipeline := exec.Command("/bin/sh", "-c", cmd)
	pipeline.Dir = path
	var out bytes.Buffer
	var stderr bytes.Buffer
	pipeline.Stdout = &out
	pipeline.Stderr = &stderr
	err := pipeline.Run()
	if err != nil {
		return stderr.String(), err
	}
	return out.String(), nil
}

func ExecCommandGitWithRootAndOutput(cmd, path string) (string, error) {
	pipeline := exec.Command("/bin/sh", "-c", cmd)
	pipeline.Dir = path
	var stderr bytes.Buffer
	pipeline.Stdout = os.Stdout
	pipeline.Stderr = &stderr
	err := pipeline.Run()
	if err != nil {
		return stderr.String(), err
	}
	return "", nil
}

func ExecCommand(cmd string) ([]byte, error) {
	pipeline := exec.Command("/bin/sh", "-c", cmd)
	var out bytes.Buffer
	var stderr bytes.Buffer
	pipeline.Stdout = &out
	pipeline.Stderr = &stderr
	err := pipeline.Run()
	if err != nil {
		return stderr.Bytes(), err
	}
	// fmt.Println(stderr.String())
	return out.Bytes(), nil
}

func ExecCommandString(cmd string) (string, error) {
	pipeline := exec.Command("/bin/sh", "-c", cmd)
	var out bytes.Buffer
	var stderr bytes.Buffer
	pipeline.Stdout = &out
	pipeline.Stderr = &stderr
	err := pipeline.Run()
	if err != nil {
		return stderr.String(), err
	}
	return out.String(), nil
}

func IsPathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}
